#include"polynomial.h"

template<int order>
double polynomial<order>::get_value_at_x(double x){
    double px = coeff[order];
    for(int i = order; i > 0; i--){
        px = px * x + coeff[i - 1];
    }
    return px;
}

template<int order>
void polynomial<order>::print_poly(){
    cout << "(" << coeff[order] << ")";
    if(order == 1) cout << "x";
    if(order >= 2) cout << "x^" << order;
    for(int i = order-1; i >= 0; i--){
        cout << "+(" << coeff[i] << ")";
        if(i == 1) cout << "x";
        if(i >= 2) cout << "x^" << i;
    }
    cout << endl;
    return;
}

template class polynomial<0>;
template class polynomial<1>;
template class polynomial<2>;
template class polynomial<3>;

polynomial<3> cubic_0_2_val(double a, double b,
                        double fa, double fb,
                        double Ma, double Mb)
{
    vector<double> coeff;
    double f0 = fa - fb;
    double f1 = b*fa - a*fb;
    double M0 = Ma - Mb;
    double M1 = b*Ma - a*Mb;
    double M2 = b*b*Ma - a*a*Mb;
    double M3 = b*b*b*Ma - a*a*a*Mb;
    double delta = a - b;
    coeff.push_back(-M3/6.0/delta - f1/delta + delta*M1/6.0); 
    coeff.push_back(M2/2.0/delta + f0/delta - delta*M0/6.0); 
    coeff.push_back(-M1/2.0/delta); 
    coeff.push_back(M0/6.0/delta); 
    polynomial<3> S(coeff);
    return S;
}

polynomial<1> linear_0_val(double a, double b,
                        double fa, double fb)
{
    vector<double> coeff;
    double f0 = fa - fb;
    double f1 = b*fa - a*fb;
    double delta = a - b;
    coeff.push_back(-f1/delta); 
    coeff.push_back(f0/delta); 
    polynomial<1> S(coeff);
    return S;
}